package com.android.project.games;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.util.Log;

import com.android.project.framework.impl.GLGame;
import com.android.project.framework.math.Vector2;
import com.android.project.framework.util.AssociationIO;
import com.android.project.framework.util.AssociationWords;
import com.android.project.mysql.connection.AssociationWord;

public class World {
	public interface WorldListener1{
		public void semi();
		public void wrong();
		public void right();
	
	}
	
//	public static final Vector2 gravity = new Vector2(0, -10);
//	public static final float WORLD_WIDTH = 10;
	//public static final float WORLD_HEIGHT = 15 * 4;
	public static final float WORLD_WIDTH = 320;
	public static final float WORLD_HEIGHT = 480;
	public static final int WORLD_STATE_READY = 0;
	public static final int WORLD_STATE_RUNNING = 1;
	public static final int WORLD_STATE_GAME_PAUSED = 2;
	public static final int WORLD_STATE_LEVEL_END = 3;
	public static final int WORLD_GAME_OVER = 4;

	public List<Label> labels;
	int score;
	WorldListener1 listener;
	int state;
	Label newLabel;
	boolean keyboardShow = false;
	float render = 0;
	boolean pressBack = false;
	Vector2 positionTouch;
	Vector2 positionTouchPrev;
	//String resultCheck;
	Random rand;
	public List<Line> lines;
	static int err;
	static int lastY;
	int level;

	
	
	public World(WorldListener1 listener, String word, int level){
		
		labels = new ArrayList<Label>();
		this.listener = listener;
		this.score = 40;
		this.state = WORLD_STATE_READY;
		render = 0;
		keyboardShow= false;
		positionTouch = new Vector2();
		positionTouchPrev = new Vector2();
		lines = new ArrayList<Line>();
		//resultCheck = "";
		err = 0;
		rand = new Random();
		this.level = level + 3;
		generateLevel(word);
		
		
		
	
	}
	
	public void generateLevel(String w){
	
		if(labels.isEmpty()){	
			
			newLabel = new Label(160, 240);
			newLabel.setWord(w);
			newLabel.state = Label.LABEL_STATE_INPUT;
			labels.add(newLabel);
			
			//updateLabel(deltaTime);
			//Assets.playSound(Assets.guillotineSound);
					
			
		}
		while(labels.size() < 2) {
				float x = newLabel.position.x;
				float y = newLabel.position.y;
				if(lines ==  null) Log.d("world1", "lines is null");
				lines.add(new Line(newLabel.position, new Vector2(x + 50 , y + 80)));
				newLabel = new Label(x + 50 , y + 80);
				newLabel.setWord("");
				labels.add(newLabel);
		}
	}

	public void update(float deltaTime){
		updateWorld(deltaTime);
		checkLevelEnd();
		checkGameOver();


	}

	private void checkLevelEnd() {
		// TODO Auto-generated method stub
		
		int i = labels.size();
		
	//	if(i == 5 && labels.get(i - 2).state != Label.LABEL_STATE_INSERT){
		if(i == level){
			
			state = WORLD_STATE_LEVEL_END;
			keyboardShow = false;
			render = 4;
			
		}
	
	
	}

	public void updateWorld(float deltaTime) {
		// TODO Auto-generated method stub
		if(pressBack){
			keyboardShow = false;
			//render = 0;
			return;
		}
		if(this.state == WORLD_STATE_GAME_PAUSED){
			render = 0;
			keyboardShow= false;
			return;
			
		}
		else if(this.state == WORLD_STATE_RUNNING && keyboardShow){
			render = 3;
			keyboardShow= true;
			//Log.d("world1", "render 3");
			return;
		}
		/*else if(this.state == WORLD_STATE_LEVEL_END){
			keyboardShow = false;
			render = 0;
			return;
		}*/
	
	}

	private void checkGameOver() {
		// TODO Auto-generated method stub
		if(this.score == 0){
			state = WORLD_GAME_OVER;
			render = 0;
			keyboardShow = false;
			
		}
		
		
	}

	public List<Label> getLabels() {
		return labels;
	}


			
	public int checkWord(List<AssociationWord> words, GLGame game){
		Vector2 pos = new Vector2();
		
		this.render = 2;
		
		for(int i = 1; i < labels.size(); i++){
			Label l = labels.get(i);
	
			String check = words.get(1).getWord();
			if(check.equalsIgnoreCase(l.getWord()) && l.writeEnable){
				score += 50;
				//l.state = Label.LABEL_STATE_RIGHT;
				listener.right();
				//l.writeEnable = false;
				l.update(Label.LABEL_STATE_RIGHT, false);
				//this.resultCheck = String.valueOf(0);
				pos = addLabel(l);
				lines.add(new Line(pos, l.position));
				err = 0;
				return 0;
			}
			if(l.writeEnable ){
				for(int j= 2; j < words.size(); j++){
					if(words.get(j).getWord().equals(l.getWord())){
						score -= 5;
						//l.state = Label.LABEL_STATE_SEMI;
						//l.writeEnable = false;
						l.update(Label.LABEL_STATE_SEMI, false);
						listener.semi();
					//	this.resultCheck = String.valueOf(j);
						pos = addLabel(l);
						lines.add(new Line(l.position, pos));
						err = 0;
						return j;
					}
				}	
				score -= 10;			
				//l.state = Label.LABEL_STATE_WRONG;
				listener.wrong();
				//l.writeEnable = false;
				l.update(Label.LABEL_STATE_WRONG, false);
			//	this.resultCheck = String.valueOf(-1);
				err++;
				pos = addLabel(labels.get(i -err)); 
				lines.add(new Line(labels.get(i -err).position, pos));
				return -1;
			}
	
		}
	
		return -2;
	}

	private Vector2 addLabel(Label position2) {
		
		// TODO Auto-generated method stub
		float y = 0;
		float x = 0;
		
		float posXOvest = position2.position.x - 144;
		float posXEst = position2.position.x + 144;
		float posYOvest = position2.position.y - 16;
		float posYEst = position2.position.y + 16;
		
		
		
		//Log.d("posx ",  " " + posXOvest);
		//Log.d("posx ",  " " + posXEst);
		
		Label last = labels.get(labels.size() - 1);
		Label prev = labels.get(labels.size() - 2);

		
		if(state == WORLD_STATE_RUNNING){
			
				if(last.state == Label.LABEL_STATE_WRONG){
					
				
					if(last.position.x != (posXOvest - 200)  && prev.position.x != (posXOvest - 200) ){
						
						
						Log.d("prova 1 ",  " " );
						x = posXOvest - 200;
						y = position2.position.y;
						newLabel = new Label( x , y);
					    labels.add(newLabel);
					    return newLabel.position;
					}
					if(last.position.x != (posXEst + 200) && prev.position.x != (posXEst + 200) ){
						
						Log.d("prova 2 ",  " " );
						x = posXEst + 200;
						y = position2.position.y;
						newLabel = new Label( x , y);
					    labels.add(newLabel);
					    return newLabel.position;
						
					}
				}
				for(int i = 0; i < labels.size(); i++){
					Label l = labels.get(i);
					if(!(l.position.x > 160 && l.position.y > 240)){
						//Log.d("prova 13 ",  " " );
						x = posXEst + 160;
						y = posYEst + 80;
						newLabel = new Label( x , y);
					    labels.add(newLabel);
					    return newLabel.position;
						//i = labels.size();
					}
					if(!(l.position.x < 160 && l.position.y > 240)){
						//Log.d("prova 4 ",  " " );
						x = posXOvest - 160;
						y = posYOvest + 80;
						newLabel = new Label( x , y);
					    labels.add(newLabel);
					    return newLabel.position;
						//i = labels.size();
					}
					if(!(l.position.x < 160 && l.position.y < 240)){
						//Log.d("prova 5 ",  " " );
						x = posXOvest - 160;
						y = posYOvest - 80;
						newLabel = new Label( x , y);
					    labels.add(newLabel);
					    return newLabel.position;
						//i = labels.size();
					}
					if(!(l.position.x > 160 && l.position.y < 240)){
						x = posXEst + 160;
						y = posYEst - 80;
						newLabel = new Label( x , y);
					    labels.add(newLabel);
					    return newLabel.position;
						//i = labels.size();
					}
					
				}
				if(x == 0 && y== 0 ){
					x= rand.nextInt(320);
					y= rand.nextInt(480);
				}
			
			/*Log.d("x ",  " " + x);
			

			Log.d("y ",  " " + y);*/
			newLabel = new Label( x , y);
		    labels.add(newLabel);
		    return newLabel.position;
		}
		
		
		return null;
		
		
	}

	public void enableLabel(String s) {
		// TODO Auto-generated method stub
		int m = labels.size() ;
		for(int i = 0; i < m; i++){
			if(labels.get(i).state == Label.LABEL_STATE_INSERT) {
				labels.get(i).setWord(s);
				labels.get(i).writeEnable = true;
				return;
			}
				
		}
		
	}


}
